﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using SKYPE4COMLib;

namespace SkypeBot.Core
{
    using SkypeBotCore;

    public class Core 
    {
        public IList<Message> Messages = new List<Message>();
        public Article ArticleManager { get; set; }
        public List<Receiver> Receivers { get; set; }
        public LaunchMode CurrentLaunchMode { get; set; }
        public MessageHandler CurrentMessageHandler { get { return _messageHandler; } }    
        public UserCollection Users { get; set; }
        public ChatCollection Chats { get; set; }

        private Scheduler.Scheduler _scheduler;
        private Skype _skypeMachine;
        private SkypeBotLoop _skypeBotLoop;

        private bool _isBotStarted;
        private MessageHandler _messageHandler = new MessageHandler();

        public enum LaunchMode { Dev, Prod }



        protected Core() { }
 
        private sealed class CoreCreator
        {
             private static readonly Core instance = new Core();
             public static Core Instance { get { return instance; } }
        }
 
        public static Core Instance
        {
             get { return CoreCreator.Instance; }
        }

        public void StartBot()
        {
            if (!_isBotStarted)
            {
                AttachToSkype();
                StartSkypeBotLoop();
                InitSkypeMachine();

                _isBotStarted = true;
                Users = _skypeMachine.Friends;
                Chats = _skypeMachine.Chats;
                Receivers = new List<Receiver>();
                _scheduler = new Scheduler.Scheduler();

                RunMongoServer();
            }
        }

        private void skype_machine_OnlineStatus(User pUser, TOnlineStatus Status)
        {     
            if (_skypeMachine.CurrentUser.Handle != pUser.Handle)
            {
                string mstrMessage = string.Empty;
                switch ((int)Status)
                {
                    case 1:
                        mstrMessage = string.Format("Привет {0}, йопта!!!", pUser.FullName); 
                        break;
                    case 2:
                        mstrMessage = string.Format("Еее... {0} куда же ты???", pUser.FullName);
                        break;
                    case 3:
                        mstrMessage = string.Format("Пока {0}, надеюсь ты вернешся :(", pUser.FullName);
                        break;
                    case 4:
                        mstrMessage = string.Format("Вай-вай, какой {0} занятой...", pUser.FullName);
                        break;
                    default: break;
                }

                SendToRecievers(new Responce(mstrMessage));
            }
        }

        void skype_machine_UserStatus(TUserStatus Status)
        {
            if (Status == TUserStatus.cusOnline)
            {
                SendToRecievers(new Responce("Привет, я тутась йопта!!!"));
                }
            }

        public void StopBot()
        {
            if (_isBotStarted)
            {
                _skypeMachine = null;
                _skypeBotLoop.Stop();
                _isBotStarted = false;
            }
        }

        void skype_machine_MessageStatus(ChatMessage pMessage, TChatMessageStatus Status)
        {
                if (pMessage.Sender.Handle != _skypeMachine.CurrentUser.Handle)
                {
                    if (pMessage.Timestamp < DateTime.Now.AddSeconds(-4))
                    {
                        pMessage.Seen = true;
                    }
                    else
                    {
                        Message objMessage = new Message(pMessage.Id, pMessage.Sender.Handle, pMessage.Body, pMessage.Timestamp, pMessage.ChatName);
                        MarasHandler.HandleMaras(objMessage);
                        AccordionDetector.CheckMessageOnAccordion(objMessage);
                        if (objMessage != null)
                        { 
                            // Messages.Add(objMessage);
                            Responce objResponce = _messageHandler.Handle(objMessage); // executor.ExecuteCommand(objMessage);
                            SendToRecievers(objResponce);
                        }
                    }
                }
        }

        public void SendToRecievers(Responce objResponce)
        {
            if (objResponce != null && !string.IsNullOrEmpty(objResponce.Message))
            {
                if (objResponce.Receiver == null)
                {
                    foreach (Receiver mobjReceiver in Receivers)
                    {
                        SendMessage(mobjReceiver.ReceiverName, objResponce.Message, mobjReceiver.IsChat);
                    }
                }
                else
                {
                    objResponce.Receiver = new Receiver("#yarikdarkmoon/$52ca93efc058c976", true);
                    SendMessage(objResponce);
                }
            }
        }


        public void SendMessage(Responce objResponce)
        {
            SendMessage(objResponce.Receiver.ReceiverName, objResponce.Message, objResponce.Receiver.IsChat);
        }

        public void SendMessage(string name, string msg, bool IsChat)
        {
            if (CurrentLaunchMode == LaunchMode.Dev)
            {
                Console.OutputEncoding = Encoding.UTF8;
                Console.WriteLine(string.Format("Message to {0}: {1}", name, msg));
            }
            else if (CurrentLaunchMode == LaunchMode.Prod)
            {
                if (!string.IsNullOrEmpty(msg))
                {
                    if (!_isBotStarted)
                    {
                        StartBot();
                    }

                    if (IsChat)
                    {
                        _skypeMachine.Chat[name].SendMessage(msg);
                    }
                    else { _skypeMachine.SendMessage(name, msg); }
                    }
            }
        }

        private void AttachToSkype()
        {
            _skypeMachine = new Skype();
            if (!_skypeMachine.Client.IsRunning)
            {
                _skypeMachine.Client.Start(true, true);
            }

            _skypeMachine.Attach(6);
        }

        private void InitSkypeMachine()
        {
            _skypeMachine.MessageStatus += skype_machine_MessageStatus;
            _skypeMachine.UserStatus += skype_machine_UserStatus;
            _skypeMachine.OnlineStatus += skype_machine_OnlineStatus;
        }

        private void StartSkypeBotLoop()
        {
            if (_skypeBotLoop == null)
            {
                _skypeBotLoop = new SkypeBotLoop();
            }

            _skypeBotLoop.Start();            
        }

        private void RunMongoServer()
        {
            string strPathToMongoServer = Path.Combine(Path.GetPathRoot(Environment.SystemDirectory), "MongoServer");
            string strServerPath = Path.Combine(strPathToMongoServer, "bin\\mongod.exe");
            Process.Start(strServerPath);
        }
    }
}
